home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / t_os / catlog / source / file.c < prev    next >
C/C++ Source or Header  |  1993-07-08  |  16KB  |  606 lines

  1. /*
  2.     NIFTYのLOG整理                file.c
  3.                     by GHH01217 山先
  4.     $Header: FILE.Cv  1.2  93/02/12 22:45:08  山先  Exp $
  5. */
  6.  
  7. #include    "log.h"
  8. #include    <dir.h>
  9.  
  10. #define    TEST    1
  11. #undef    TEST
  12.  
  13. /************************************************************************/
  14. /*                                                                      */
  15. /*   file の 入出力の高速化のために                                     */
  16. /*                                                                      */
  17. /************************************************************************/
  18.  
  19. static    char    *sentinel;
  20. static    FILE    *pool_fpi;
  21. static    char    *catlog_pool=NULL;
  22. static    char    *check_sentinel , *check_head , *pool_end;
  23. static    int        catlog_pool_append_0a_sw;
  24.  
  25. void    insert_char( char *start , int c )
  26. {
  27.     if (    start < catlog_pool
  28.     ||        check_sentinel < start
  29.     ||        pool_end < start
  30.     ) {
  31.         sprintf(str,"領域外です。%2xを追加できません" , c );
  32.         error_bug( str );    return;
  33.     };
  34.     if ( pool_end <= check_sentinel ) {
  35.         sprintf(str,"領域不足です。%2xを追加できません。\n" , c );
  36.         error_bug( str );    return;
  37.     };
  38.     memmove( start + 1 , start , check_sentinel - start );
  39.     *start = c;
  40.  
  41.     /********************/
  42.     /* ポインタ類の更新 */
  43.     /********************/
  44.     if ( start < LastStrPtr )                LastStrPtr++;
  45.     if ( start < PresentStrPtr )            PresentStrPtr++;
  46.     if ( start < NextStrPtr )                NextStrPtr++;
  47.     if ( start < check_head )                check_head++;
  48.     if ( start < sentinel )                    sentinel++;
  49.     if ( start < check_sentinel )            check_sentinel++;
  50.     if ( start < check_pool_delete_start )    check_pool_delete_start++;
  51. }
  52.  
  53. static    void    delete_line( char *start , char *end )
  54. {
  55.     int    len;
  56.  
  57.     if ( start == end )        return;
  58.     if ( start == NULL )    return;
  59.     if ( end == NULL )        return;
  60.  
  61.     if ( start < catlog_pool || end < catlog_pool ) {
  62.         sprintf(str,"delete_line 管理領域を破壊します<%ld> <%ld>",
  63.             start - catlog_pool,
  64.             end - catlog_pool
  65.         );
  66.         error_bug( str );    return;
  67.     };
  68.  
  69.     len = end - start;
  70.     memmove( start , end , check_sentinel - end );
  71.  
  72.     /********************/
  73.     /* ポインタ類の更新 */
  74.     /********************/
  75.     if ( start < LastStrPtr && LastStrPtr < end ) {
  76.         LastStrPtr = start;
  77.     } else {
  78.         if ( end <= LastStrPtr ) LastStrPtr = LastStrPtr - len;
  79.     };
  80.  
  81.     if ( start < PresentStrPtr && PresentStrPtr < end ) {
  82.         PresentStrPtr = start;
  83.     } else {
  84.         if ( end <= PresentStrPtr ) PresentStrPtr = PresentStrPtr - len;
  85.     };
  86.  
  87.     if ( start < NextStrPtr && NextStrPtr < end ) {
  88.         NextStrPtr = start;
  89.     } else {
  90.         if ( end <= NextStrPtr ) NextStrPtr = NextStrPtr - len;
  91.     };
  92.  
  93.     if ( start < check_head && check_head < end ) {
  94.         check_head = start;
  95.     } else {
  96.         if ( end <= check_head ) check_head = check_head - len;
  97.     };
  98.  
  99.     if ( start < sentinel && sentinel < end ) {
  100.         sentinel = start;
  101.     } else {
  102.         if ( end <= sentinel ) sentinel = sentinel - len;
  103.     };
  104.  
  105.     if ( start < check_pool_delete_start && check_pool_delete_start < end ) {
  106.         check_pool_delete_start = start;
  107.     } else {
  108.         if ( end <= check_pool_delete_start ) {
  109.             check_pool_delete_start = check_pool_delete_start - len;
  110.         };
  111.     };
  112.  
  113.     /* 空いた領域を 0 で埋める */
  114. /*
  115.     for ( p=check_sentinel-len; p<check_sentinel ; p++ ) *p = '\0';
  116. */
  117. }
  118.  
  119. static    int    catlog_fread_char;
  120. static    int    catlog_fread_char_sw = NO;
  121.  
  122. static    int    catlog_fread( char *pool1 )
  123. {
  124.     int    c,len1,len2,sw;
  125.  
  126. #ifdef    TEST
  127.     printf("catlog_fread()だよ ");
  128. #endif
  129.  
  130.     sw = 0;
  131.     if ( catlog_fread_char_sw != NO ) {
  132.         sw = 1;
  133.         *pool1++                = catlog_fread_char;
  134.         catlog_fread_char_sw    = NO;
  135.     };
  136.  
  137.     len1 = check_sentinel - pool1;        /* ロードするバイト数 */
  138.     if ( len1 < 0 ) {
  139.         strcpy(str,"catlog_fread ちゃんと領域を確保してね。" );
  140.         error_bug( str );    return( 0 );
  141.     };
  142.  
  143.     if ( pool1 < catlog_pool ) {
  144.         sprintf(str,"catlog_fread 管理領域を破壊しますよ。<%ld> ",
  145.             pool1 - catlog_pool
  146.         );
  147.         error_bug( str );    return( 0 );
  148.     };
  149.  
  150.     /* ロードしたバイト数 */
  151.     len2 = fread( pool1 , sizeof(char) , len1 , pool_fpi );
  152.  
  153.     if ( len2 < len1 ) {
  154.         c = fgetc( pool_fpi );        /* set EOF flag */
  155.         if ( c != EOF ) {
  156.             catlog_fread_char        = c;
  157.             catlog_fread_char_sw    = YES;
  158.         } else {
  159.             catlog_fread_char_sw    = NO;
  160.         };
  161.     };
  162.  
  163. #ifdef    TEST
  164.     printf("%dバイトロードしたよ。\n" , len2 , sw );
  165. #endif
  166.  
  167.     sentinel = pool1 + len2;
  168.     return ( len2 + sw );
  169. }
  170.  
  171. static    int    load_sentinel()
  172. {
  173.     int    len;
  174.  
  175.     if ( catlog_pool <= check_pool_delete_start ) {
  176.         delete_line( catlog_pool , check_pool_delete_start );
  177.     };
  178.     if ( sentinel == check_sentinel ) {
  179.         strcpy(str,"確保した作業領域より発言の方が大きいので、"
  180.                     "データをロードできません。"
  181.         );
  182.         error_bug( str );    return( 0 );
  183.     };
  184.     len = catlog_fread( sentinel );
  185.     return( len );
  186. }
  187.  
  188. static    char    *set_next_str()
  189. {
  190.     int    len;
  191.  
  192.     NextStrPtr = check_head;
  193.     NextStrLen = 0;
  194.  
  195.     if ( check_head == NULL )    return( PresentStrPtr );
  196.  
  197.     if ( check_head >= sentinel ) {
  198.         if ( feof( pool_fpi ) != 0 )    {        /* EOF */
  199.             NextStrPtr = NULL;    NextStrLen = 0;
  200.             return( PresentStrPtr );
  201.         };
  202.         /* 処理済みの行を削除 */
  203.         len = load_sentinel();
  204.         /* 以下は必要ないが……… */
  205.         if ( len == 0 ) {            /* EOF */
  206.             NextStrLen = check_head - NextStrPtr;
  207.             check_head = NULL;
  208.             return( PresentStrPtr );
  209.         };
  210.     };
  211.  
  212.     while ( *check_head != 0x0d ) {
  213.         if ( *check_head == 0x1a ) {    /* ^Z */
  214.             /* 処理済みの行を削除 */
  215.             /* 空白にする */
  216.             *check_head = ' ';
  217. /*
  218.             delete_line( check_head , check_head + 1 );
  219.             continue;
  220. */
  221.         };
  222.         check_head++;
  223.         if ( check_head >= sentinel ) {
  224.             if ( feof( pool_fpi ) != 0 )    break;    /* EOF */
  225.             /* 処理済みの行を削除 */
  226.             len = load_sentinel();
  227.             /* 以下は必要ないが……… */
  228.             if ( len == 0 ) {            /* EOF */
  229.                 NextStrLen = check_head - NextStrPtr;
  230.                 check_head = NULL;
  231.                 return( PresentStrPtr );
  232.             };
  233.         };
  234.     };
  235.     NextStrLen = check_head - NextStrPtr;    /* 0x0d は数えない */
  236.  
  237.     if ( *check_head == 0x0d ) check_head++;
  238.  
  239.     /* 0x0a を追加する */
  240.     if ( catlog_pool_append_0a_sw == YES && *check_head != 0x0a ) {
  241.         insert_char( check_head , 0x0a );
  242.     };
  243.     check_head++;
  244.     return( PresentStrPtr );
  245. }
  246.  
  247. /********************/
  248. /* ポインタ群の更新 */
  249. /********************/
  250. char    *catlog_fgets()
  251. {
  252.     /* ファイルの中での位置 */
  253.     if ( NextStrPtr != NULL && PresentStrPtr != NULL ) {
  254.         pool_seek_ichi += (NextStrPtr - PresentStrPtr);
  255.     };
  256.  
  257.     LastStrLen = PresentStrLen;
  258.     LastStrPtr = PresentStrPtr;
  259.  
  260.     PresentStrLen = NextStrLen;
  261.     PresentStrPtr = NextStrPtr;
  262.  
  263.     return set_next_str();        /* set next_str */
  264. }
  265.  
  266. /***************************************************/
  267. /* malloc() を使って catlog_pool[] の領域を確保する */
  268. /***************************************************/
  269. static    void    pool_malloc( size_t fsize )
  270. {
  271.     int    sw;
  272.     size_t    max,min,tmp,tuika;
  273.  
  274.     if ( catlog_pool_append_0a_sw == NO ) {    tuika = 0;
  275.     } else {        tuika = fsize * 2 / 3;
  276.     };
  277.  
  278.     if ( ( catlog_pool = (char *)malloc( (fsize + tuika)*sizeof(char) )
  279.     ) != NULL ) {
  280.         check_sentinel = catlog_pool + fsize;
  281.         pool_end = check_sentinel + tuika;
  282.         return;
  283.     };
  284.  
  285.     max = fsize;    min = 0;    tmp = ( max - min ) / 2 + min;
  286.     sw = FALSE;
  287.     while ( sw == FALSE ) {
  288.         if ( ( catlog_pool = (char *)malloc( (tmp + tuika)*sizeof(char) )
  289.         ) == NULL ) {    max = tmp;
  290.         } else {    min = tmp;    free( catlog_pool );
  291.         };
  292.         tmp = ( max - min ) / 2 + min;
  293.         if ( tmp < 1 ) {
  294.             tuika = tuika / 2;
  295.             if ( tuika == 0 ) {
  296.                 strcpy(str,"メモリーが足りません。");
  297.                 error_bug( str );    return;
  298.             };
  299.             max = fsize;    min = 0;
  300.             tmp = ( max - min ) / 2 + min;
  301.         };
  302.         if ( max == min || max - 1 == min ) sw = TRUE;
  303.     };
  304.     catlog_pool = (char *)malloc( (tmp + tuika)*sizeof(char) );
  305.     check_sentinel = catlog_pool + tmp;
  306.     pool_end = check_sentinel + tuika;
  307. }
  308.  
  309. /************************************/
  310. /* file_name のオープンと領域の確保 */
  311. /************************************/
  312. int    initial_check_pool( long fsize , int sw )
  313. {
  314.     size_t    fsize2;
  315.  
  316.     if ( catlog_pool != NULL ) {
  317.         strcpy(str,"initial_check_pool ");
  318.         error_bug( str );    return( FALSE );
  319.     };
  320.  
  321.     catlog_pool_append_0a_sw = sw;
  322.  
  323.     pool_malloc( fsize );
  324.  
  325.     check_head = catlog_pool;
  326.  
  327.     check_pool_delete_start =
  328.     LastStrPtr = PresentStrPtr = NextStrPtr = catlog_pool;
  329.     LastStrLen = PresentStrLen = NextStrLen = 0;
  330.  
  331.     pool_seek_ichi = 0;    /* ファイルの中での位置 */
  332.  
  333.     if ( ( pool_fpi = fopen( file_name ,"rb" ) ) == NULL ) {
  334.         /* 考えられないエラー */
  335.         error_open_file( "initial_check_pool" );
  336.         free( catlog_pool );    return( FALSE );
  337.     };
  338.  
  339.     setbuf( pool_fpi , NULL );    /* NON Buffered mode */
  340.  
  341.     if ( (    fsize2 = catlog_fread(catlog_pool) ) <= 0
  342.     ) {
  343.         sprintf(str,"initial_check_pool()で"
  344.             "ファイル<%s>をロードできません。\n",
  345.             file_name
  346.         );
  347.         error_bug( str );
  348.  
  349.         end_check_pool();    return( FALSE );
  350.     };
  351.  
  352.     if ( fsize == fsize2 ) fgetc( pool_fpi );    /* set EOF flag */
  353.  
  354.     set_next_str();
  355.     return( TRUE );
  356. }
  357.  
  358. /****************************/
  359. /* PresentStrPtr を削除する */
  360. /****************************/
  361. void    delete_present_line()
  362. {
  363.     if ( NextStrPtr != NULL ) delete_line( PresentStrPtr , NextStrPtr );
  364.     set_next_str();        /* set next_str */
  365. }
  366.  
  367. /****************************/
  368. /* catlog_poolを解放して終了 */
  369. /****************************/
  370. void    end_check_pool()
  371. {
  372.     fclose( pool_fpi );
  373.     if ( catlog_pool != NULL ) {
  374.         free( catlog_pool );
  375.     } else {
  376.         strcpy(str,"領域を確保していないのに解放しようとしているよ。");
  377.         error_bug( str );
  378.     };
  379.     catlog_pool = NULL;
  380. }
  381.  
  382. static    char    crlf[ 3 ] = { 0x0d , 0x0a , '\0' };
  383.  
  384. size_t    catlog_fwrite()
  385. {
  386.     size_t    len;
  387.  
  388.     if ( PresentStrPtr == NULL ) {
  389.         len = fwrite(
  390.             check_pool_delete_start ,
  391.             sizeof(char) ,
  392.             sentinel - check_pool_delete_start ,
  393.             catlog_fpo
  394.         );
  395.         if ( *(sentinel - 1 ) != 0x0a )             catlog_fprintf( "" );
  396.     } else {
  397.         len = fwrite(
  398.             check_pool_delete_start ,
  399.             sizeof(char) ,
  400.             PresentStrPtr - check_pool_delete_start ,
  401.             catlog_fpo
  402.         );
  403.         if ( *(PresentStrPtr - 1 ) != 0x0a )     catlog_fprintf( "" );
  404.     };
  405.     return( len );
  406. }
  407.  
  408. void    catlog_fprintf( const char *targ )
  409. {
  410.     int     len;
  411.  
  412.     len = strlen( targ );
  413.     if ( len != 0 ) fwrite( targ , sizeof(char) , len , catlog_fpo );
  414.  
  415.     fwrite( crlf , sizeof(char) , 2 , catlog_fpo );
  416. }
  417.  
  418. /**************************************/
  419. /* file_name のファイルの大きさを得る */
  420. /**************************************/
  421. size_t    file_size()
  422. {
  423.     size_t    fsize;
  424.     FILE    *fp;
  425.  
  426.     if ( ( fp = fopen( file_name , "r" ) ) == NULL )    return( 0 );
  427.     fclose( fp );
  428.     fp = fopen( file_name , "ab" );
  429.         fsize = ftell( fp );
  430.     fclose( fp );
  431.     return( fsize );
  432. }
  433.  
  434. /************************************************************************/
  435. /*                                                                      */
  436. /*   file 名の処理                                                      */
  437. /*                                                                      */
  438. /************************************************************************/
  439.  
  440. /*********************************/
  441. /* file の 空白を 0 に置き換える */
  442. /*********************************/
  443. void    file_name_space_0( char *file )
  444. {
  445.     while ( *file ) {
  446.         if ( *file == ' ' ) *file = '0';
  447.         file++;
  448.     };
  449. }
  450.  
  451. /************************************************************************/
  452. /*                                                                      */
  453. /*   tmp file の処理                                                    */
  454. /*                                                                      */
  455. /************************************************************************/
  456.  
  457. /*******************/
  458. /* 巨大な tmp file */
  459. /*******************/
  460. void    set_tmp0_file_name( char *file )
  461. {
  462.     sprintf( file , "%s%s" , tmp_path , TMP_FILE_NAME );
  463. }
  464.  
  465. /*********************/
  466. /* 大もとの tmp file */
  467. /*********************/
  468. static    void    tmp0_file_error( char *str )
  469. {
  470.     printf("\n%s()で<%s>をオープンできません。",str,file_name);
  471.     printf("\n\n\tドライブをきちんと設定していますか?");
  472.     printf("\n\n\t架空のドライブやCDを指定していたり、");
  473.     printf(  "\n\t残り容量の無いドライブを指定していませんか?");
  474.     printf("\n\nそれでもおかしいというのであれば");
  475.     error_bug( "原因不明" );
  476. }
  477.  
  478. void    open_out_tmp0_file()
  479. {
  480.     set_tmp0_file_name( file_name );
  481.     if ( ( catlog_fpo = fopen( file_name , "wb" )) == NULL ) {
  482.         tmp0_file_error("open_out_tmp0_file");
  483.     };
  484.  
  485.     /* NON Buffered mode */
  486. /*
  487.     setbuf( catlog_fpo , NULL );
  488. */
  489. }
  490.  
  491. void    open_append_tmp0_file()
  492. {
  493.     set_tmp0_file_name( file_name );
  494.     if ( ( catlog_fpo = fopen( file_name , "ab" )) == NULL ) {
  495.         tmp0_file_error("open_append_tmp0_file");
  496.     };
  497.  
  498.     /* NON Buffered mode */
  499. /*
  500.     setbuf( catlog_fpo , NULL );
  501. */
  502. }
  503.  
  504. void    open_read_tmp0_file()
  505. {
  506.     set_tmp0_file_name( file_name );
  507.     if ( ( catlog_fpi = fopen( file_name , "r" )) == NULL ) {
  508.         tmp0_file_error("open_read_tmp0_file");
  509.     };
  510. }
  511.  
  512. void    delete_tmp0_file()
  513. {
  514.     set_tmp0_file_name( file_name );
  515.     remove( file_name );
  516. }
  517.  
  518. int        CATLOG_tmp_file( const char *file )
  519. {
  520.     if ( strcmp( file , TMP_FILE_NAME ) == 0 )            return( YES );
  521.     if ( strcmp( file , IDX_FILE_NAME ) == 0 )            return( YES );
  522.     if ( strcmp( file , CATLOG_TIME_FILE_NAME ) == 0 )    return( YES );
  523.     if ( strcmp( file , DONE_FILE_NAME ) == 0 )            return( YES );
  524.     return( NO );
  525. }
  526.  
  527. /*****************************************/
  528. /* kaigishitsu_number を設定しておくこと */
  529. /*****************************************/
  530. void    set_index_file_name( char *new_forum )
  531. {
  532.     strcpy( file_name , output_path );
  533.     if ( Index_mode == 1 ) {
  534.         check_and_make_output_path( file_name );
  535.         strcat( file_name , IDX_FILE_NAME );            return;
  536.     };
  537.     switch( kaigishitsu_number ) {
  538.         case HP:
  539.             strcat( file_name , "HP\\" );
  540.             strcat( file_name , new_forum );            break;
  541.         case CLIP:
  542.             strcat( file_name , "CLIP\\" );                break;
  543.         case PATIO:
  544.             strcat( file_name , "PATIO\\" );
  545.             strcat( file_name , new_forum );            break;
  546.         case MAIL:
  547.         case ALL_MAIL:
  548.             strcat( file_name , "NIFMAIL\\" );            break;
  549.         case BILL:
  550.             strcat( file_name , "BILL\\" );                break;
  551.         case COLLECT_ID:
  552.             strcat( file_name , "COLLECT\\" );            break;
  553.         default:
  554.             strcat( file_name , new_forum );            break;
  555.     };
  556.     check_and_make_output_path( file_name );
  557.     strcat( file_name , "\\" );
  558.     strcat( file_name , IDX_FILE_NAME );
  559. }
  560.  
  561. /************************************************************************/
  562. /*                                                                      */
  563. /*          ソートしたデータを記録する                                  */
  564. /*                                                                      */
  565. /************************************************************************/
  566. /******************/
  567. /* 各発言のファイル名 */
  568. /******************/
  569. void    set_file_name( int count )
  570. {
  571.     char    file[ 32 ];
  572.  
  573.     switch ( kaigishitsu_number ) {
  574.         case CLIP:
  575.             sprintf( file , "CLIP\\CLIP.TX%d", count );                break;
  576.         case PATIO:
  577.             sprintf( file , "PATIO\\%s.PA%d", forum_name , count );    break;
  578.         case HP:
  579.             sprintf( file , "HP\\%s\\%s.HP%d",forum_name ,forum_name , count );
  580.             break;
  581.         case MAIL:
  582.         case ALL_MAIL:
  583.             if ( MakeUpMAILInto1FileSw == YES ) {
  584.                 sprintf( file , "NIFMAIL\\%s" , ALL_IN_1_MAIL_FILE_NAME );
  585.             } else {
  586.                 sprintf( file , "NIFMAIL\\%s.ML%d", forum_name , count );
  587.             };
  588.             break;
  589.         case BILL:    sprintf( file , "BILL\\BILL.BL%d", count );
  590.             break;
  591.         case COLLECT_ID:
  592.             sprintf( file , "COLLECT\\%s.TX%d", forum_name , count );
  593.             break;
  594.         default:
  595.             sprintf(file,"%s\\MES%2d_%2d.TXT",
  596.                 forum_name,kaigishitsu_number,count
  597.             );
  598.             break;
  599.     };
  600.     strcpy( file_name , output_path );
  601.     strcat( file_name , file );
  602.     file_name_space_0( file_name );
  603.     check_and_make_output_path( file_name );
  604. }
  605.  
  606.